package rtk;

import android.util.Base64;

import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;

import rtk.olinkstar.Buffer;

/**
 * Created by Mr.Fan on 2017/5/30.
 */

public class RtkThread extends Thread {
    public String mHost;
    public Integer mPort;
    public String mMountPoint;
    public String mAccount;
    public String mPassword;

    private Socket mSocket; // 网络接口Socket
    private boolean isCanceled = false;
    private RtkDataListener mRtkDataListener;
    private long mInterval = 1000;
    private boolean hasNewParams = false;

    private String mGGAData;


    public RtkThread() {
    }

    public void setParams(String host, Integer port, String accessPoint, String account, String password) {
        this.mHost = host;
        this.mPort = port;
        this.mMountPoint = accessPoint;
        this.mAccount = account;
        this.mPassword = password;

        this.hasNewParams = true;
    }

    public void updateGGA(String nmea) {
        this.mGGAData = nmea;
    }

    public void setInterval(long interval) {
        mInterval = interval;
    }

    public long getInterval() {
        return mInterval;
    }

    public void cancel() {
        try {
            isCanceled = true;
            interrupt();
        } catch (Exception e) {

        }
    }

    public boolean isRunning() {
        return !isCanceled && !interrupted();
    }

    public void setRtkDataListener(RtkDataListener listener) {
        mRtkDataListener = listener;
    }


    @Override
    public void run() {
        while (isRunning()) {
            InputStream is = null;
            OutputStream os = null;

            try {
                // 连接差分服务器
                SocketAddress sockaddr = new InetSocketAddress(mHost, mPort != null ? mPort : 88);
                hasNewParams = false;
                mSocket = new Socket();
                mSocket.setReuseAddress(true);
                // 设置发送逗留时间2秒 中断后未传输数据可传输的时间（秒）,defalut false
                mSocket.setSoLinger(true, 2);
                // 数据不作缓冲，立即发送
                mSocket.setTcpNoDelay(true);
                // 设置InputStream上调用 read()阻塞超时时间2秒
                mSocket.setSoTimeout(2000);
                // 设置socket发包缓冲为32k；
                mSocket.setSendBufferSize(64 * 1024);
                // 设置socket底层接收缓冲为32k
                mSocket.setReceiveBufferSize(64 * 1024);
                mSocket.connect(sockaddr, 1000);
                if (mSocket.isConnected()) {
                    if (mRtkDataListener != null)
                        mRtkDataListener.onRtkServerState(true);
                    is = mSocket.getInputStream();
                    os = mSocket.getOutputStream();

                    // 编写密码验证包
                    String requestMsg = "GET /" + mMountPoint + " HTTP/1.0\r\n";
                    requestMsg += "User-Agent: NTRIP OlinkStarAndroidNTRIPClient/20150312\r\n";
                    requestMsg += "Accept: */*\r\n";
                    requestMsg += "Connection: close\r\n";
                    requestMsg += "Authorization: Basic " + ToBase64(mAccount + ":" + mPassword);

                    requestMsg += "\r\n\r\n\n";

                    // 发送密码验证包
                    os.write(requestMsg.getBytes());

                    os.flush();
                    Thread.sleep(500);
                    int nSecCnt = 0;
                    do {
                        int read = 0;
                        int nWillReadCnt = 0;
                        int willread = 0;
                        do {
                            willread = is.available();
                            if (willread > 0 || nWillReadCnt > 100) {
                                break;
                            } else {
                                nWillReadCnt++;
                            }
                            Thread.sleep(10);
                        } while (willread <= 0 && isRunning() && !hasNewParams);
                        // 发送GGA数据***********************************************

                        final String newGGA = mGGAData;

                        if (newGGA == null) {

                        } else {
//                            String newGGA = "$GPGGA,064001.00,4002.89980754,N,11617.66644396,E,4,12,0.975,75.89467,M,,M,,*40";
                            String usedGGA = newGGA.substring(1, newGGA.indexOf("*"));
                            byte a = Buffer.xor(usedGGA.getBytes());
                            String end = "*" + Integer.toHexString(a);
                            String head = "$";
                            String newGGA2 = head.concat(usedGGA.concat(end));
                            newGGA2 = newGGA2 + "\r\n";

                            newGGA2 = newGGA2.toUpperCase();
                            Buffer.printHexString(newGGA2.getBytes());
                            Buffer.printHexString(newGGA.getBytes());

                            os.write(newGGA2.getBytes());
                        }

                        if (willread > 0) {
                            nSecCnt = 0;
                            // 持续读取数据
                            byte[] buffer = new byte[willread];
                            read = is.read(buffer, 0, willread);
                            if (read > 0) {

                                // 原始数据
                                byte[] tmpprint = new byte[read];
                                System.arraycopy(buffer, 0, tmpprint, 0, read);
//                                mBleManager.setRtcmThread(true);
//                                mBleManager.SdkData(tmpprint, true);
                                mRtkDataListener.onRtkData(tmpprint);
                            } else {
                                Thread.sleep(mInterval);
                            }
                        } else {
                            nSecCnt++;
                            Thread.sleep(mInterval);
                        }
                    }
                    while ((mSocket != null && mSocket.isConnected() == true) && (nSecCnt < 10) && isRunning() && !hasNewParams);

                } else {
                    if (mRtkDataListener != null)
                        mRtkDataListener.onRtkServerState(false);
                    Thread.sleep(mInterval);
                }

            } catch (Exception e) {
                e.printStackTrace();
                try {
                    Thread.sleep(mInterval);
                } catch (InterruptedException e1) {

                }
            } finally {
                try {
                    // 重连时候缓冲区还有老数据
                    if (is != null) {
                        try {
                            is.close();
                        } catch (Exception e) {

                        }
                    }
                    if (os != null) {
                        try {
                            os.close();
                        } catch (Exception e) {

                        }
                    }
                    if (mSocket != null) {
                        try {
                            mSocket.close();
                        } catch (Exception e) {

                        }
                        mSocket = null;
                    }
                    if (mRtkDataListener != null)
                        mRtkDataListener.onRtkServerState(false);
                } catch (Exception e) {

                }
            }
        }
        if (mRtkDataListener != null)
            mRtkDataListener.onRtkServerState(false);
    }

    private String ToBase64(String in) {
        return Base64.encodeToString(in.getBytes(), 4);
    }

    public interface RtkDataListener {
        void onRtkData(byte[] data);

        void onRtkServerState(boolean conn);
    }
}
